<script setup>
import { computed, getCurrentInstance, ref } from "vue";
import { getToken } from "@/utils/auth";
import { AdminToken } from "@/utils/constant";
import config from "@/utils/config";

const { proxy } = getCurrentInstance()
const props = defineProps({
  // 上传文件类型
  type: {
    type: Number,
    default: 1
  },
  // 是否支持多选
  multiple: {
    type: Boolean,
    default: true
  },
  // 多选时最大数量
  limit: {
    type: Number,
    default: 10
  },
  // 上传时额外参数
  data: {
    type: Object,
    default: {}
  },
  // 是否显示上传进度
  showProgress: {
    type: Boolean,
    default: false
  }
})

const emit = defineEmits(['change', 'error', 'success', 'allSuccess'])
const fileList = ref([]);
const uploadRef = ref();
const action = ref(import.meta.env.VITE_IMG_URL + '/upload')
const headers = computed(() => ({
  [AdminToken]: getToken(AdminToken)
}))
const visible = ref(false)
let uploadLen = 0;

const handleProgress = (info) => {
  visible.value = true;
}

const handleSuccess = (info) => {
  const { file } = info;
  uploadLen++;
  if (uploadLen === fileList.value.length) {
    uploadLen = 0;
    fileList.value = [];
    emit('allSuccess');
  }
  emit('change', file);

  if (file.response.code === 200) {
    proxy.$modal.okNotify('上传成功')
    emit('success', file.response);
  }
  if(file.response.code === 500){
    proxy.$modal.errorNotify(file.response.msg)
  }
}

const handleExceed = () => {
  proxy.$modal.errorNotify('上传文件数量不能超过' + props.limit + '个')
}

const handleError = (info) => {
  const { file } = info;
  uploadLen++;
  if (uploadLen === fileList.value.length) {
    uploadLen = 0;
    fileList.value = [];
    emit('allSuccess');
  }
  proxy.$modal.errorNotify(`${file.name}文件上传失败`)
  visible.value = false;
  emit('change', file);
  emit('error', file);
}

const handleClose = () => {
  fileList.value = []
  visible.value = false
}

const handleChange = (info) => {
  const { file, fileList: newFileList } = info;

  fileList.value = newFileList;

  if (file.status === 'uploading') {
    handleProgress(info);
  } else if (file.status === 'done') {
    handleSuccess(info);
  } else if (file.status === 'error') {
    handleError(info);
  }

  if (newFileList.length > props.limit) {
    handleExceed();
    fileList.value = newFileList.slice(0, props.limit);
  }
}

const getAccept = computed(() => {
  switch (props.type) {
    case 1:
      return config.acceptImgType.join(',')
    case 2:
      return config.acceptVideoType.join(',')
    case 3:
      return config.acceptFileType.join(',')
  }
})
</script>

<template>
  <div class="upload">
    <a-upload
        v-model:file-list="fileList"
        ref="uploadRef"
        :action="action"
        :multiple="multiple"
        :max-count="limit"
        :show-upload-list="false"
        :headers="headers"
        :data="data"
        :accept="getAccept"
        @change="handleChange"
    >
      <slot/>
    </a-upload>

    <a-modal
        v-if="showProgress && fileList.length"
        v-model:open="visible"
        title="上传进度"
        :maskClosable="false"
        width="500px"
        :mask="false"
        @cancel="handleClose"
    >
      <div class="file-list p-4">
        <template v-for="(item, index) in fileList" :key="index">
          <div class="mb-5">
            <div>{{ item.name }}</div>
            <div class="flex-1">
              <a-progress
                  :percent="parseInt(item.percent.toFixed(0))"
              />
            </div>
          </div>
        </template>
      </div>
    </a-modal>
  </div>
</template>

<style scoped lang="scss">
.upload {
  :deep(.ant-upload) {
    width: 100%;
  }
}
</style>
